package org.example.meetingsystem.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.meetingsystem.DTO.PaymentDTO;
import org.example.meetingsystem.DTO.ReservationRequestDTO;
import org.example.meetingsystem.entity.MeetingRoom;
import org.example.meetingsystem.entity.Reservation;
import org.example.meetingsystem.entity.User;
import org.example.meetingsystem.enums.ReservationStatus;
import org.example.meetingsystem.enums.UserRole;
import org.example.meetingsystem.annotation.RequireAuth;
import org.example.meetingsystem.mapper.ReservationMapper;
import org.example.meetingsystem.service.ReservationService;
import org.example.meetingsystem.util.BusinessException;
import org.example.meetingsystem.util.ResponseUtil;
import org.example.meetingsystem.util.Result;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/api/reservations")
@RequiredArgsConstructor
@Slf4j
@Tag(name = "预订管理")
public class ReservationController {

    private final ReservationMapper reservationMapper;
    private final ReservationService reservationService;

    /**
     * 客户查看自己的预订记录
     */
    @GetMapping("/my")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "查看我的预订记录")
    public Result<List<Reservation>> getMyReservations(HttpServletRequest request) {
        User currentUser = (User) request.getAttribute("currentUser");
        List<Reservation> reservations = reservationMapper.selectByCustomerId(currentUser.getId());
        return ResponseUtil.success(reservations);
    }

    /**
     * 客户查看自己的符合取消条件的预订记录
     */
    @GetMapping("/can-cancel")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "查看我的可取消预订记录")
    public Result<List<Reservation>> getMyCanCancelReservations(HttpServletRequest request) {
        User currentUser = (User) request.getAttribute("currentUser");

        List<Reservation> cancellableReservations = reservationMapper.selectCancellableByCustomerId(currentUser.getId());

        return ResponseUtil.success(cancellableReservations);
    }

    /**
     * 检查会议室可用性
     */
    @GetMapping("/check-availability")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "检查会议室可用性")
    public Result<List<MeetingRoom>> checkAvailability(
            @RequestParam @Parameter(ref = "开始时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime startTime,
            @RequestParam @Parameter(ref = "结束时间") @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
            @RequestParam @Parameter(ref = "参会人数") Integer attendeeCount,
            @RequestParam(required = false) @Parameter(ref = "是否需要投影仪") Boolean needProjector,
            @RequestParam(required = false) @Parameter(ref = "是否需要音响") Boolean needAudio,
            @RequestParam(required = false) @Parameter(ref = "是否需要网络") Boolean needNetwork) {

        if (startTime.isBefore(LocalDateTime.now()) || endTime.isBefore(startTime)) {
            return ResponseUtil.error("时间参数无效");
        }

        List<MeetingRoom> availableRooms = reservationService.findAvailableRooms(
                startTime, endTime, attendeeCount, needProjector, needAudio, needNetwork);

        return ResponseUtil.success(availableRooms);
    }

    /**
     * 创建预订
     */
    @PostMapping("/{roomId}")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "创建预订")
    public Result<Reservation> createReservation(
            @PathVariable @Parameter(ref = "会议室ID") Long roomId,
            @RequestBody @Valid ReservationRequestDTO requestDTO,
            HttpServletRequest request) {

        User currentUser = (User) request.getAttribute("currentUser");

        try {
            Reservation reservation = reservationService.createReservation(
                    currentUser.getId(), roomId, requestDTO);
            return ResponseUtil.success("预订创建成功，请在30分钟内完成支付", reservation);
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        }
    }

    /**
     * 支付预订
     */
    @PostMapping("/{id}/payment")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "支付预订")
    public Result<String> payReservation(
            @PathVariable @Parameter(ref = "预订ID") Long id,
            @RequestBody PaymentDTO paymentDTO,
            HttpServletRequest request) {

        try {
            reservationService.payReservation(id, paymentDTO);
            return ResponseUtil.success("支付成功");
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        }
    }

    /**
     * 申请取消预订
     */
    @PostMapping("/{id}/cancel")
    @RequireAuth(roles = {UserRole.CUSTOMER})
    @Operation(summary = "申请取消预订")
    public Result<String> cancelReservation(
            @PathVariable @Parameter(ref = "预订ID") Long id,
            @RequestParam(required = false) @Parameter(ref = "取消原因") String reason,
            HttpServletRequest request) {

        User currentUser = (User) request.getAttribute("currentUser");

        try {
            reservationService.cancelReservation(id, currentUser.getId(), reason);
            return ResponseUtil.success("取消申请已提交，等待审核");
        } catch (BusinessException e) {
            return ResponseUtil.error(e.getMessage());
        }
    }

    /**
     * 员工查看所有预订记录
     */
    @GetMapping
    @RequireAuth(roles = {UserRole.EMPLOYEE, UserRole.ADMIN})
    @Operation(summary = "查看所有预订记录")
    public Result<IPage<Reservation>> getAllReservations(
            @RequestParam(defaultValue = "1") @Parameter(ref = "页码") Integer current,
            @RequestParam(defaultValue = "10") @Parameter(ref = "每页数量") Integer size,
            @RequestParam(required = false) @Parameter(ref = "预订状态") ReservationStatus status,
            @RequestParam(required = false) @Parameter(ref = "会议室ID") Long roomId,
            @RequestParam(required = false) @Parameter(ref = "客户ID") Long customerId) {

        Page<Reservation> page = new Page<>(current, size);
        QueryWrapper<Reservation> queryWrapper = new QueryWrapper<>();

        if (status != null) {
            queryWrapper.eq("status", status);
        }
        if (roomId != null) {
            queryWrapper.eq("room_id", roomId);
        }
        if (customerId != null) {
            queryWrapper.eq("customer_id", customerId);
        }

        queryWrapper.orderByDesc("created_at");
        IPage<Reservation> result = reservationMapper.selectPage(page, queryWrapper);

        return ResponseUtil.success(result);
    }

    /**
     * 员工查看今日预订情况
     */
    @GetMapping("/today")
    @RequireAuth(roles = {UserRole.EMPLOYEE, UserRole.ADMIN})
    @Operation(summary = "查看今日预订情况")
    public Result<List<Reservation>> getTodayReservations() {
        List<Reservation> reservations = reservationMapper.selectTodayReservations();
        return ResponseUtil.success(reservations);
    }

    /**
     * 员工更新预订状态
     */
    @PutMapping("/{id}/status")
    @RequireAuth(roles = {UserRole.EMPLOYEE, UserRole.ADMIN})
    @Operation(summary = "更新预订状态")
    public Result<String> updateReservationStatus(
            @PathVariable @Parameter(ref = "预订ID") Long id,
            @RequestParam @Parameter(ref = "预订状态") ReservationStatus status) {

        Reservation reservation = new Reservation();
        reservation.setId(id);
        reservation.setStatus(status);
        reservationMapper.updateById(reservation);

        return ResponseUtil.success("预订状态更新成功");
    }
}
